package drds.configuration.web.common.servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * @author caozhenghui@drds.team<330937205@qq.com>
 */
@SuppressWarnings("serial")
public class ValidateCodeServlet extends HttpServlet {
    public static final String Code = "code";
    private int width;
    private int height;
    private int number;
    private String codes;

    private int dotNum;
    private int lineNum;

    public static void clearCode(HttpServletRequest request) {
        if (request == null) {
            throw new NullPointerException("request");
        }
        request.getSession().setAttribute(Code, null);

    }

    @Override
    public void destroy() {
        super.destroy();
    }

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("image/jpeg");
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2d = bufferedImage.createGraphics();
        graphics2d.setColor(Color.WHITE);
        graphics2d.fillRect(0, 0, width, height);
        graphics2d.setColor(Color.black);
        graphics2d.drawRect(0, 0, width - 1, height - 1);
        int x = width / number;
        int y = height - 4;
        Random random = new Random();
        String randomCode = "";
        for (int i = 0; i < number; i++) {
            String code = String.valueOf(codes.charAt(random.nextInt(codes.length())));
            int red = random.nextInt(255);
            int green = random.nextInt(255);
            int black = random.nextInt(255);
            graphics2d.setColor(new Color(red, green, black));
            Font font = new Font("黑体", Font.BOLD, this.radomMin2Max(20, 25));
            graphics2d.setFont(font);
            graphics2d.drawString(code, x * i, y);
            randomCode += code;
        }

        for (int i = 0; i < dotNum; i++) {
            int red = random.nextInt(255);
            int green = random.nextInt(255);
            int black = random.nextInt(255);
            graphics2d.setColor(new Color(red, green, black));
            graphics2d.drawOval(random.nextInt(width), random.nextInt(height), 1, 1);
        }

        graphics2d.setColor(Color.BLACK);
        for (int i = 0; i < lineNum; i++) {
            x = random.nextInt(width);
            y = random.nextInt(height);
            int xl = random.nextInt(lineNum);
            int yl = random.nextInt(lineNum);
            graphics2d.drawLine(x, y, x + xl, y + yl);
        }

        HttpSession session = request.getSession();
        session.setAttribute(Code, randomCode.toString());
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        ServletOutputStream servletOutputStream = response.getOutputStream();
        ImageIO.write(bufferedImage, "jpeg", servletOutputStream);
        servletOutputStream.close();
    }

    @Override
    public void init() throws ServletException {
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        width = Integer.parseInt(config.getInitParameter("width"));
        height = Integer.parseInt(config.getInitParameter("height"));
        number = Integer.parseInt(config.getInitParameter("number"));
        codes = config.getInitParameter("codes");
        dotNum = Integer.parseInt(config.getInitParameter("dotNum"));
        lineNum = Integer.parseInt(config.getInitParameter("lineNum"));
    }

    private int radomMin2Max(int min, int max) {
        Random random = new Random();
        int randomNum = (min + max) / 2;
        for (int i = 0; i < 100; i++) {
            int radomInner = random.nextInt(max);
            if (radomInner < min) {
                continue;
            } else {
                randomNum = radomInner;
                break;
            }
        }
        return randomNum;
    }
}
